home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 21 / AACD 21.iso / AACD / Utilities / Ghostscript / src / gsistate.c < prev    next >
Encoding:
C/C++ Source or Header  |  2001-01-01  |  8.9 KB  |  286 lines

  1. /* Copyright (C) 1999, 2000 Aladdin Enterprises.  All rights reserved.
  2.   
  3.   This file is part of AFPL Ghostscript.
  4.   
  5.   AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND.  No author or
  6.   distributor accepts any responsibility for the consequences of using it, or
  7.   for whether it serves any particular purpose or works at all, unless he or
  8.   she says so in writing.  Refer to the Aladdin Free Public License (the
  9.   "License") for full details.
  10.   
  11.   Every copy of AFPL Ghostscript must include a copy of the License, normally
  12.   in a plain ASCII text file named PUBLIC.  The License grants you the right
  13.   to copy, modify and redistribute AFPL Ghostscript, but only under certain
  14.   conditions described in the License.  Among other things, the License
  15.   requires that the copyright notice and this notice be preserved on all
  16.   copies.
  17. */
  18.  
  19. /*$Id: gsistate.c,v 1.4 2000/09/19 19:00:29 lpd Exp $ */
  20. /* Imager state housekeeping */
  21. #include "gx.h"
  22. #include "gserrors.h"
  23. #include "gscspace.h"
  24. #include "gscie.h"
  25. #include "gsstruct.h"
  26. #include "gsutil.h"        /* for gs_next_ids */
  27. #include "gxbitmap.h"
  28. #include "gxcmap.h"
  29. #include "gxdht.h"
  30. #include "gxistate.h"
  31. #include "gzht.h"
  32. #include "gzline.h"
  33.  
  34. /******************************************************************************
  35.  * See gsstate.c for a discussion of graphics/imager state memory management. *
  36.  ******************************************************************************/
  37.  
  38. /* Imported values */
  39. /* The following should include a 'const', but for some reason */
  40. /* the Watcom compiler won't accept it, even though it happily accepts */
  41. /* the same construct everywhere else. */
  42. extern /*const*/ gx_color_map_procs *const cmap_procs_default;
  43.  
  44. /* Structure descriptors */
  45. private_st_imager_state_shared();
  46.  
  47. /* GC procedures for gx_line_params */
  48. private
  49. ENUM_PTRS_WITH(line_params_enum_ptrs, gx_line_params *plp) return 0;
  50.     case 0: return ENUM_OBJ((plp->dash.pattern_size == 0 ?
  51.                  NULL : plp->dash.pattern));
  52. ENUM_PTRS_END
  53. private RELOC_PTRS_WITH(line_params_reloc_ptrs, gx_line_params *plp)
  54. {
  55.     if (plp->dash.pattern_size)
  56.     RELOC_VAR(plp->dash.pattern);
  57. } RELOC_PTRS_END
  58. private_st_line_params();
  59.  
  60. /* GC procedures for gs_imager_state */
  61. public_st_imager_state();
  62. private 
  63. ENUM_PTRS_BEGIN(imager_state_enum_ptrs)
  64.     ENUM_SUPER(gs_imager_state, st_line_params, line_params, st_imager_state_num_ptrs - st_line_params_num_ptrs);
  65.     ENUM_PTR(0, gs_imager_state, shared);
  66.     ENUM_PTR(1, gs_imager_state, client_data);
  67.     ENUM_PTR(2, gs_imager_state, opacity.mask);
  68.     ENUM_PTR(3, gs_imager_state, shape.mask);
  69.     ENUM_PTR(4, gs_imager_state, transparency_stack);
  70. #define E1(i,elt) ENUM_PTR(i+5,gs_imager_state,elt);
  71.     gs_cr_state_do_ptrs(E1)
  72. #undef E1
  73. ENUM_PTRS_END
  74. private RELOC_PTRS_BEGIN(imager_state_reloc_ptrs)
  75. {
  76.     RELOC_SUPER(gs_imager_state, st_line_params, line_params);
  77.     RELOC_PTR(gs_imager_state, shared);
  78.     RELOC_PTR(gs_imager_state, client_data);
  79.     RELOC_PTR(gs_imager_state, opacity.mask);
  80.     RELOC_PTR(gs_imager_state, shape.mask);
  81.     RELOC_PTR(gs_imager_state, transparency_stack);
  82. #define R1(i,elt) RELOC_PTR(gs_imager_state,elt);
  83.     gs_cr_state_do_ptrs(R1)
  84. #undef R1
  85. } RELOC_PTRS_END
  86.  
  87. /* Free device color spaces. */
  88. void
  89. gx_device_color_spaces_free(gx_device_color_spaces_t *pdcs, gs_memory_t *mem,
  90.                 client_name_t cname)
  91. {
  92.     int i;
  93.  
  94.     for (i = countof(pdcs->indexed); --i >= 0; ) {
  95.     gs_color_space *pcs = pdcs->indexed[i];
  96.  
  97.     if (pcs) {
  98.         gs_cspace_release(pcs);
  99.         gs_free_object(mem, pcs, cname);
  100.     }
  101.     }
  102. }
  103.  
  104. /* Initialize an imager state, other than the parts covered by */
  105. /* gs_imager_state_initial. */
  106. private float
  107. imager_null_transfer(floatp gray, const gx_transfer_map * pmap)
  108. {
  109.     return gray;
  110. }
  111. private void
  112. rc_free_imager_shared(gs_memory_t * mem, void *data, client_name_t cname)
  113. {
  114.     gs_imager_state_shared_t * const shared =
  115.     (gs_imager_state_shared_t *)data;
  116.  
  117.     gx_device_color_spaces_free(&shared->device_color_spaces, mem,
  118.                 "shared device color space");
  119.     rc_free_struct_only(mem, data, cname);
  120. }
  121.  
  122. int
  123. gs_imager_state_initialize(gs_imager_state * pis, gs_memory_t * mem)
  124. {
  125.     pis->memory = mem;
  126.     pis->client_data = 0;
  127.     /* Preallocate color spaces. */
  128.     {
  129.     int code;
  130.     gs_imager_state_shared_t *shared;
  131.  
  132.     rc_alloc_struct_1(shared, gs_imager_state_shared_t,
  133.               &st_imager_state_shared, mem,
  134.               return_error(gs_error_VMerror),
  135.               "gs_imager_state_init(shared)");
  136.     shared->device_color_spaces.named.Gray =
  137.         shared->device_color_spaces.named.RGB =
  138.         shared->device_color_spaces.named.CMYK = 0; /* in case we bail out */
  139.     shared->rc.free = rc_free_imager_shared;
  140.     if ((code = gs_cspace_build_DeviceGray(&shared->device_color_spaces.named.Gray, mem)) < 0 ||
  141.         (code = gs_cspace_build_DeviceRGB(&shared->device_color_spaces.named.RGB, mem)) < 0 ||
  142.         (code = gs_cspace_build_DeviceCMYK(&shared->device_color_spaces.named.CMYK, mem)) < 0
  143.         ) {
  144.         rc_free_imager_shared(mem, shared, "gs_imager_state_init(shared)");
  145.         return code;
  146.     }
  147.     pis->shared = shared;
  148.     }
  149.     pis->opacity.mask = 0;
  150.     pis->shape.mask = 0;
  151.     pis->transparency_stack = 0;
  152.     /* Color rendering state */
  153.     pis->halftone = 0;
  154.     {
  155.     int i;
  156.  
  157.     for (i = 0; i < gs_color_select_count; ++i)
  158.         pis->screen_phase[i].x = pis->screen_phase[i].y = 0;
  159.     }
  160.     pis->dev_ht = 0;
  161.     pis->ht_cache = 0;
  162.     pis->cie_render = 0;
  163.     pis->black_generation = 0;
  164.     pis->undercolor_removal = 0;
  165.     /* Allocate an initial transfer map. */
  166.     rc_alloc_struct_n(pis->set_transfer.colored.gray,
  167.               gx_transfer_map, &st_transfer_map,
  168.               mem, return_error(gs_error_VMerror),
  169.               "gs_imager_state_init(transfer)", 4);
  170.     pis->set_transfer.colored.gray->proc = imager_null_transfer;
  171.     pis->set_transfer.colored.gray->id = gs_next_ids(1);
  172.     pis->set_transfer.colored.gray->values[0] = frac_0;
  173.     pis->set_transfer.colored.red =
  174.     pis->set_transfer.colored.green =
  175.     pis->set_transfer.colored.blue =
  176.     pis->set_transfer.colored.gray;
  177.     pis->effective_transfer = pis->set_transfer;
  178.     pis->cie_joint_caches = 0;
  179.     pis->cmap_procs = cmap_procs_default;
  180.     pis->pattern_cache = 0;
  181.     return 0;
  182. }
  183.  
  184. /*
  185.  * Make a temporary copy of a gs_imager_state.  Note that this does not
  186.  * do all the necessary reference counting, etc.  However, it does
  187.  * clear out the transparency stack in the destination.
  188.  */
  189. gs_imager_state *
  190. gs_imager_state_copy(const gs_imager_state * pis, gs_memory_t * mem)
  191. {
  192.     gs_imager_state *pis_copy =
  193.     gs_alloc_struct(mem, gs_imager_state, &st_imager_state,
  194.             "gs_imager_state_copy");
  195.  
  196.     if (pis_copy) {
  197.     *pis_copy = *pis;
  198.     pis_copy->transparency_stack = 0;
  199.     }
  200.     return pis_copy;
  201. }
  202.  
  203. /* Increment reference counts to note that an imager state has been copied. */
  204. void
  205. gs_imager_state_copied(gs_imager_state * pis)
  206. {
  207.     rc_increment(pis->shared);
  208.     rc_increment(pis->opacity.mask);
  209.     rc_increment(pis->shape.mask);
  210.     rc_increment(pis->halftone);
  211.     rc_increment(pis->dev_ht);
  212.     rc_increment(pis->cie_render);
  213.     rc_increment(pis->black_generation);
  214.     rc_increment(pis->undercolor_removal);
  215.     rc_increment(pis->set_transfer.colored.gray);
  216.     rc_increment(pis->set_transfer.colored.red);
  217.     rc_increment(pis->set_transfer.colored.green);
  218.     rc_increment(pis->set_transfer.colored.blue);
  219.     rc_increment(pis->cie_joint_caches);
  220. }
  221.  
  222. /* Adjust reference counts before assigning one imager state to another. */
  223. void
  224. gs_imager_state_pre_assign(gs_imager_state *pto, const gs_imager_state *pfrom)
  225. {
  226.     const char *const cname = "gs_imager_state_pre_assign";
  227.  
  228. #define RCCOPY(element)\
  229.     rc_pre_assign(pto->element, pfrom->element, cname)
  230.  
  231.     RCCOPY(cie_joint_caches);
  232.     RCCOPY(set_transfer.colored.blue);
  233.     RCCOPY(set_transfer.colored.green);
  234.     RCCOPY(set_transfer.colored.red);
  235.     RCCOPY(set_transfer.colored.gray);
  236.     RCCOPY(undercolor_removal);
  237.     RCCOPY(black_generation);
  238.     RCCOPY(cie_render);
  239.     RCCOPY(dev_ht);
  240.     RCCOPY(halftone);
  241.     RCCOPY(shape.mask);
  242.     RCCOPY(opacity.mask);
  243.     RCCOPY(shared);
  244. #undef RCCOPY
  245. }
  246.  
  247. /* Release an imager state. */
  248. void
  249. gs_imager_state_release(gs_imager_state * pis)
  250. {
  251.     const char *const cname = "gs_imager_state_release";
  252.     gx_device_halftone *pdht = pis->dev_ht;
  253.  
  254. #define RCDECR(element)\
  255.     rc_decrement(pis->element, cname)
  256.  
  257.     RCDECR(cie_joint_caches);
  258.     RCDECR(set_transfer.colored.gray);
  259.     RCDECR(set_transfer.colored.blue);
  260.     RCDECR(set_transfer.colored.green);
  261.     RCDECR(set_transfer.colored.red);
  262.     RCDECR(undercolor_removal);
  263.     RCDECR(black_generation);
  264.     RCDECR(cie_render);
  265.     /*
  266.      * If we're going to free the device halftone, make sure we free the
  267.      * dependent structures as well.
  268.      */
  269.     if (pdht != 0 && pdht->rc.ref_count == 1) {
  270.     /* Make sure we don't leave dangling pointers in the cache. */
  271.     gx_ht_cache *pcache = pis->ht_cache;
  272.  
  273.     if (pcache->order.bit_data == pdht->order.bit_data ||
  274.         pcache->order.levels == pdht->order.levels
  275.         )
  276.         gx_ht_clear_cache(pcache);
  277.     gx_device_halftone_release(pdht, pdht->rc.memory);
  278.     }
  279.     RCDECR(dev_ht);
  280.     RCDECR(halftone);
  281.     RCDECR(shape.mask);
  282.     RCDECR(opacity.mask);
  283.     RCDECR(shared);
  284. #undef RCDECR
  285. }
  286.